"use client";

import { Token } from "../types/api";
import Image from "next/image";
import {
  Copy,
  ExternalLink,
  X,
  Twitter,
  Send,
  Globe,
  MessageCircle,
} from "lucide-react";
import { toast } from "react-hot-toast";
import { useState, useEffect } from "react";
import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { apiClient } from "../lib/api";
import { VersionedTransaction, PublicKey } from "@solana/web3.js";
import { getAssociatedTokenAddress, getAccount } from "@solana/spl-token";
import { CandlestickChart } from "./CandlestickChart";
import { generateCandlestickData } from "../utils/chartData";
import { formatPrice, formatMarketCap } from "../utils/formatters";
import { io } from "socket.io-client";

interface TokenDetailModalProps {
  token: Token | null;
  onClose: () => void;
}

const StatItem = ({
  label,
  value,
}: {
  label: string;
  value: string | number;
}) => (
  <div className="flex justify-between items-center">
    <span className="text-sm text-gray-400">{label}</span>
    <span className="text-sm font-medium text-white">{value}</span>
  </div>
);

const SocialLink = ({
  href,
  icon,
  text,
}: {
  href?: string;
  icon: React.ReactNode;
  text: string;
}) => {
  if (!href) return null;
  return (
    <a
      href={href}
      target="_blank"
      rel="noopener noreferrer"
      className="flex items-center gap-2 text-sm text-gray-300 hover:text-purple-400 transition-colors"
    >
      {icon}
      <span>{text}</span>
    </a>
  );
};

export function TokenDetailModal({ token, onClose }: TokenDetailModalProps) {
  const { publicKey, sendTransaction } = useWallet();
  const { connection } = useConnection();
  const [tradeMode, setTradeMode] = useState<"buy" | "sell">("buy");
  const [amount, setAmount] = useState("");
  const [loading, setLoading] = useState(false);
  const [currentPrice, setCurrentPrice] = useState(token?.price || 0.00001);
  const [chartData, setChartData] = useState(() => 
    generateCandlestickData(token?.price || 0.00001, 30)
  );
  
  // 用户代币余额状态
  const [userBalance, setUserBalance] = useState<number>(0);
  const [userRawAmount, setUserRawAmount] = useState<string>("0");
  const [userSolBalance, setUserSolBalance] = useState<number>(0);
  const [balanceLoading, setBalanceLoading] = useState(false);

  // 更新图表数据当代币改变时
  useEffect(() => {
    if (token) {
      setCurrentPrice(token.price);
      setChartData(generateCandlestickData(token.price, 30));
    }
  }, [token]);

  // WebSocket 连接和价格监听
  useEffect(() => {
    if (!token) return;

    let socket: ReturnType<typeof io> | null = null;
    
    const connectWebSocket = () => {
      try {
        const wsUrl = apiClient.getWebSocketUrl();
        socket = io(wsUrl, {
          transports: ['websocket', 'polling'],
          autoConnect: true,
          reconnection: true,
          reconnectionAttempts: 5,
          reconnectionDelay: 1000,
        });

        socket.on('connect', () => {
          console.log('Connected to WebSocket for price updates');
          // 订阅代币价格更新
          socket?.emit('subscribe_token', { mint: token.mint });
        });

        socket.on('token_price_update', (data: { mint: string; price: number; marketCap: number; timestamp: string }) => {
          if (data.mint === token.mint) {
            console.log('Received price update:', data);
            setCurrentPrice(data.price);
            
            // 更新蜡烛图数据
            setChartData(prevData => {
              const newData = [...prevData];
              if (newData.length > 0) {
                const latest = { ...newData[newData.length - 1] };
                latest.close = data.price;
                latest.high = Math.max(latest.high, data.price);
                latest.low = Math.min(latest.low, data.price);
                newData[newData.length - 1] = latest;
              }
              return newData;
            });
          }
        });

        socket.on('disconnect', () => {
          console.log('Disconnected from WebSocket');
        });

        socket.on('connect_error', (error: Error) => {
          console.error('WebSocket connection error:', error);
        });
      } catch (error) {
        console.error('Failed to create WebSocket connection:', error);
      }
    };

    connectWebSocket();

    return () => {
      if (socket) {
        socket.emit('unsubscribe_token', { mint: token.mint });
        socket.disconnect();
      }
    };
  }, [token]);

  // 获取用户代币余额
  useEffect(() => {
    const fetchUserBalance = async () => {
      if (!token || !publicKey || !connection) return;
      
      setBalanceLoading(true);
      try {
        const mintPublicKey = new PublicKey(token.mint);
        const associatedTokenAddress = await getAssociatedTokenAddress(
          mintPublicKey,
          publicKey
        );
        
        try {
          const tokenAccount = await getAccount(connection, associatedTokenAddress);
          // 保存原始代币数量用于显示
          const rawAmount = tokenAccount.amount.toString();
          setUserRawAmount(rawAmount);
          
          // 同时保存转换后的余额用于计算价值
          const balance = Number(tokenAccount.amount) / 1_000_000_000;
          console.log('代币余额调试:', {
            tokenSymbol: token.symbol,
            rawAmount: rawAmount,
            rawAmountFormatted: Number(rawAmount).toLocaleString(),
            calculatedBalance: balance,
            tokenMint: token.mint
          });
          setUserBalance(balance);
        } catch {
          // 账户不存在，余额为0
          setUserBalance(0);
          setUserRawAmount("0");
        }
      } catch (error) {
        console.error("Failed to fetch user balance:", error);
        setUserBalance(0);
      } finally {
        setBalanceLoading(false);
      }
    };

    fetchUserBalance();
  }, [token, publicKey, connection]);

  // 获取用户 SOL 余额
  useEffect(() => {
    const fetchSolBalance = async () => {
      if (!publicKey || !connection) return;
      
      try {
        const balance = await connection.getBalance(publicKey);
        const solBalance = balance / 1_000_000_000; // 转换为 SOL
        setUserSolBalance(solBalance);
      } catch (error) {
        console.error("Failed to fetch SOL balance:", error);
        setUserSolBalance(0);
      }
    };

    fetchSolBalance();
  }, [publicKey, connection]);

  if (!token) return null;

  const handleTrade = async () => {
    if (!publicKey) {
      toast.error("请先连接钱包");
      return;
    }
    if (!amount || parseFloat(amount) <= 0) {
      toast.error("请输入有效的数额");
      return;
    }
    
    // 检查卖出时的余额
    if (tradeMode === "sell") {
      const sellAmount = parseFloat(amount);
      const userRawAmountNumber = Number(userRawAmount);
      
      if (sellAmount > userRawAmountNumber) {
        toast.error(`代币数量不足。您只有 ${userRawAmountNumber.toLocaleString()} 个代币`);
        return;
      }
    }
    
    // 检查代币是否已毕业
    if (token.isGraduated) {
      toast.error("此代币已毕业，无法通过联合曲线系统进行交易。请前往 Raydium 或其他 DEX 进行交易。");
      return;
    }

    setLoading(true);
    toast.loading("正在处理交易...", { id: "trade-toast" });

    try {
      let response;
      if (tradeMode === "buy") {
        // 购买代币，使用 SOL 数量
        response = await apiClient.buyToken(
          token.mint,
          parseFloat(amount), // SOL 数量
          publicKey.toBase58()
        );
      } else {
        // 卖出代币，使用代币数量
        response = await apiClient.sellToken(
          token.mint,
          parseFloat(amount), // 代币数量
          publicKey.toBase58()
        );
      }

      console.log("API Response:", response);

      if (response.success && response.data?.transaction) {
        const transactionData = response.data.transaction;
        try {
          // 尝试反序列化交易
          console.log("Raw transaction data:", transactionData);

          // 使用浏览器兼容的方式解码 base64
          let transactionBuffer: Uint8Array;
          try {
            // 方法 1: 使用 Buffer（Node.js 风格）
            transactionBuffer = Buffer.from(
              transactionData,
              "base64"
            );
          } catch {
            console.log("Buffer failed, trying atob...");
            // 方法 2: 使用 atob（浏览器原生）
            const binaryString = atob(transactionData);
            transactionBuffer = new Uint8Array(binaryString.length);
            for (let i = 0; i < binaryString.length; i++) {
              transactionBuffer[i] = binaryString.charCodeAt(i);
            }
          }

          console.log("Transaction buffer length:", transactionBuffer.length);

          const transaction =
            VersionedTransaction.deserialize(transactionBuffer);
          console.log("Transaction deserialized successfully");
          console.log("Transaction details:", {
            version: transaction.version,
            signatures: transaction.signatures.length,
            message: transaction.message,
          });

          // 发送交易
          console.log("Attempting to send transaction...");
          const txid = await sendTransaction(transaction, connection, {
            skipPreflight: false,
            preflightCommitment: "processed",
            maxRetries: 3,
          });

          console.log("Transaction sent:", txid);
          
          // 记录交易到数据库
          try {
            const recordResponse = await apiClient.recordTransaction({
              signature: txid,
              type: tradeMode.toUpperCase() as 'BUY' | 'SELL',
              tokenMint: token.mint,
              userPublicKey: publicKey?.toString() || '',
              amount: parseFloat(amount),
              metadata: {
                timestamp: Date.now(),
                price: currentPrice,
                tradeMode: tradeMode
              }
            });
            
            if (recordResponse.success) {
              console.log("Transaction recorded successfully");
            } else {
              console.warn("Failed to record transaction:", recordResponse.message);
            }
          } catch (recordError) {
            console.error("Error recording transaction:", recordError);
            // 不影响主流程，只是记录失败
          }
          
          // 显示交易结果信息
          if (response.data.signature || txid) {
            const finalTxId = response.data.signature || txid;
            toast.success(`交易成功: ${finalTxId}`, { id: "trade-toast" });
            
            // 显示详细信息
            if (tradeMode === "buy" && "tokenAmount" in response.data && response.data.tokenAmount) {
              toast.success(`获得 ${response.data.tokenAmount} ${token.symbol}`, { duration: 5000 });
            } else if (tradeMode === "sell" && "solAmount" in response.data && response.data.solAmount) {
              toast.success(`获得 ${response.data.solAmount} SOL`, { duration: 5000 });
            }
            
            // 检查是否毕业
            if ("isGraduated" in response.data && response.data.isGraduated) {
              toast.success("🎓 代币已毕业！", { duration: 8000 });
            }
          }

          // 更新图表数据（使用实际价格或模拟价格变化）
          const newPrice = response.data.price || (token.price * (tradeMode === 'buy' ? 1.01 : 0.99));
          setCurrentPrice(newPrice);
          
          const updatedChartData = [...chartData];
          if (updatedChartData.length > 0) {
            // 更新最新的蜡烛数据
            const latest = updatedChartData[updatedChartData.length - 1];
            latest.close = newPrice;
            latest.high = Math.max(latest.high, newPrice);
            latest.low = Math.min(latest.low, newPrice);
            latest.volume += parseFloat(amount);
            setChartData([...updatedChartData]);
          }

          // 清空输入
          setAmount("");
        } catch (txError: unknown) {
          console.error("Transaction processing error:", txError);
          console.error("Error details:", JSON.stringify(txError, null, 2));

          let errorMessage = "交易处理失败";
          if (txError instanceof Error) {
            errorMessage = txError.message;
            console.error("Error stack:", txError.stack);
          } else if (typeof txError === "object" && txError !== null) {
            errorMessage = JSON.stringify(txError);
          }

          throw new Error(`交易处理失败: ${errorMessage}`);
        }
      } else {
        throw new Error(response.message || "API 调用失败");
      }
    } catch (error: unknown) {
      console.error("交易失败:", error);
      let errorMessage = "未知错误";

      // 检查是否是 axios 错误
      if (error && typeof error === 'object' && 'response' in error) {
        const axiosError = error as {
          response?: {
            data?: {
              error?: string;
              message?: string;
            };
          };
          message?: string;
        };
        
        if (axiosError.response?.data?.error) {
          errorMessage = axiosError.response.data.error;
        } else if (axiosError.response?.data?.message) {
          errorMessage = axiosError.response.data.message;
        } else if (axiosError.message) {
          errorMessage = axiosError.message;
        }
      } else if (error instanceof Error) {
        errorMessage = error.message;
      } else if (typeof error === "string") {
        errorMessage = error;
      }

      toast.error(`交易失败: ${errorMessage}`, { id: "trade-toast" });
    } finally {
      setLoading(false);
    }
  };

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
    toast.success("已复制到剪贴板");
  };

  return (
    <>
      {/* Overlay */}
      <div
        className={`fixed inset-0 bg-black/60 transition-opacity duration-300 z-[100] ${token ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}`}
        onClick={onClose}
      />

      {/* Right Drawer */}
      <div
  className={`pixel-modal fixed top-0 right-0 h-full w-[90vw] md:w-[520px] lg:w-[560px] shadow-2xl z-[110] transform transition-transform duration-300 ease-in-out ${
          token ? 'translate-x-0' : 'translate-x-full'
        }`}
      >
      <div className="flex flex-col h-full">
        {/* Header */}
  <div className="flex justify-between items-center p-5 md:p-6 border-b border-gray-600">
          <h2 className="text-xl font-bold font-pixel">token details</h2>
          <button
            onClick={onClose}
            className="text-gray-400 hover:text-white transition-colors"
          >
            <X size={24} />
          </button>
        </div>

        {/* Content */}
  <div className="flex-grow p-6 md:p-8 pt-8 md:pt-10 overflow-y-auto space-y-8">
          {/* Token Info */}
          <div className="flex items-start gap-6">
            {token.image ? (
              <Image
                src={token.image}
                alt={token.name}
                width={64}
                height={64}
                className="rounded-full object-cover"
              />
            ) : (
              <div className="w-16 h-16 bg-gradient-to-br from-purple-500 to-indigo-600 rounded-full flex items-center justify-center">
                <span className="text-white font-bold text-2xl">
                  {token.symbol.charAt(0)}
                </span>
              </div>
            )}
            <div className="flex-1 min-w-0">
              <div className="flex items-center gap-2 mb-1">
                <h3 className="text-2xl font-bold truncate font-body">{token.name}</h3>
                {token.isGraduated && (
                  <span className="inline-flex items-center px-3 py-1 text-xs font-medium bg-yellow-400 text-black border-2 border-black">
                    🎓 已毕业
                  </span>
                )}
              </div>
              <p className="text-sm text-gray-400 font-mono">{token.symbol}</p>
              <div className="flex items-center gap-2 mt-1">
                <p className="text-xs text-gray-500 font-mono truncate">
                  {token.mint}
                </p>
                <button
                  onClick={() => copyToClipboard(token.mint)}
                  className="text-gray-400 hover:text-white"
                >
                  <Copy size={14} />
                </button>
                <a
                  href={`https://solscan.io/token/${token.mint}`}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="text-gray-400 hover:text-white"
                >
                  <ExternalLink size={14} />
                </a>
              </div>
            </div>
          </div>

          {/* Stats */}
          <div className="pixel-card p-5 md:p-6 space-y-4">
            <StatItem label="价格" value={formatPrice(currentPrice)} />
            <StatItem label="市值" value={formatMarketCap(token.marketCap)} />
            <StatItem label="持有者" value={token.holders.toLocaleString()} />
            
            {/* 用户余额信息 */}
            {publicKey && (
              <div className="border-t border-gray-700 pt-3 mt-3">
                <div className="text-sm text-gray-400 mb-2">我的持仓</div>
                <StatItem 
                  label="代币数量" 
                  value={balanceLoading ? "加载中..." : (
                    userRawAmount === "0" ? "0" : Number(userRawAmount).toLocaleString()
                  )}
                />
                <StatItem 
                  label="SOL 余额" 
                  value={`${userSolBalance.toLocaleString(undefined, {
                    minimumFractionDigits: 4,
                    maximumFractionDigits: 4
                  })} SOL`}
                />
                <StatItem 
                  label="价值" 
                  value={balanceLoading ? "加载中..." : (() => {
                    // 对于联合曲线代币，使用 SOL 价格计算更准确的价值
                    if (token.isBondingCurve) {
                      // 这里我们需要使用 SOL 计价而不是 USD 计价
                      // 临时使用简化计算：如果用户最近买入，价值应该接近买入成本
                      const usdValue = userBalance * currentPrice;
                      const estimatedSolValue = userBalance * 0.2 / 0.000632; // 基于最近交易估算
                      
                      console.log('联合曲线代币价值计算:', {
                        userBalance,
                        currentPrice,
                        usdValue,
                        estimatedSolValue,
                        tokenSymbol: token.symbol
                      });
                      
                      if (estimatedSolValue > 0.001) {
                        return `≈${estimatedSolValue.toFixed(6)} SOL (${formatPrice(estimatedSolValue * 150)})`;
                      } else {
                        return formatPrice(usdValue);
                      }
                    } else {
                      const calculatedValue = userBalance * currentPrice;
                      return formatPrice(calculatedValue);
                    }
                  })()}
                />
              </div>
            )}
          </div>

          {/* Chart */}
          <div className="pixel-card p-5 md:p-6">
            <CandlestickChart data={chartData} />
          </div>

          {/* Social Links */}
          <div className="pixel-card p-5 md:p-6 space-y-4">
            <h4 className="text-md font-semibold mb-2 font-pixel">社交链接</h4>
            <div className="flex flex-wrap items-center gap-3 md:gap-4">
              <SocialLink
                href={token.website}
                icon={<Globe size={16} />}
                text="官网"
              />
              <SocialLink
                href={token.twitter}
                icon={<Twitter size={16} />}
                text="Twitter"
              />
              <SocialLink
                href={token.telegram}
                icon={<Send size={16} />}
                text="Telegram"
              />
              <SocialLink
                href={token.discord}
                icon={<MessageCircle size={16} />}
                text="Discord"
              />
            </div>
          </div>

          {/* Description */}
          {token.description && (
            <div className="pixel-card p-5 md:p-6">
              <h4 className="text-md font-semibold mb-2 font-pixel">描述</h4>
              <p className="text-sm text-gray-300 font-body">{token.description}</p>
            </div>
          )}
        </div>

        {/* Actions */}
  <div className="p-6 md:p-8 border-t border-gray-700 space-y-5">
          {token.isGraduated ? (
            // 毕业代币显示提示信息
            <div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
              <div className="flex items-center space-x-2 mb-2">
                <span className="text-2xl">🎓</span>
                <h4 className="text-lg font-semibold text-yellow-800">代币已毕业</h4>
              </div>
              <p className="text-yellow-700 text-sm">
                此代币已从联合曲线系统毕业，现在在去中心化交易所（DEX）进行交易。
              </p>
              <div className="mt-3">
                <a
                  href={`https://raydium.io/swap/?inputCurrency=sol&outputCurrency=${token.mint}`}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="inline-flex items-center px-4 py-2 bg-yellow-600 text-white text-sm font-medium rounded-lg hover:bg-yellow-700 transition-colors"
                >
                  在 Raydium 交易
                  <svg className="ml-2 w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
                  </svg>
                </a>
              </div>
            </div>
          ) : (
            // 非毕业代币显示交易界面
      <>
    <div className="flex bg-gray-800 p-2 gap-2">
                <button
                  onClick={() => setTradeMode("buy")}
          className={`pixel-btn flex-1 text-md font-bold transition-colors ${
                    tradeMode === "buy"
            ? "bg-green-600 text-white"
            : "bg-gray-600 hover:bg-gray-500"
                  }`}
                >
                  Buy
                </button>
                <button
                  onClick={() => setTradeMode("sell")}
          className={`pixel-btn flex-1 text-md font-bold transition-colors ${
                    tradeMode === "sell"
            ? "bg-red-600 text-white"
            : "bg-gray-600 hover:bg-gray-500"
                  }`}
                >
                  Sell
                </button>
              </div>

        <div className="relative mt-2">
                <input
                  type="number"
                  value={amount}
                  onChange={(e) => setAmount(e.target.value)}
                  placeholder={`输入 ${
                    tradeMode === "buy" ? "SOL 数量" : `${token.symbol} 代币数量`
                  }`}
                  className="pixel-input w-full"
                />
                <div className="absolute right-3 top-1/2 transform -translate-y-1/2 text-sm text-gray-400">
                  {tradeMode === "buy" ? "SOL" : token.symbol}
                </div>
              </div>

              {/* 余额显示和最大值按钮 */}
              {publicKey && tradeMode === "sell" && (
                <div className="flex justify-between items-center text-sm text-gray-400 mt-2">
                  <span>
                    可用代币数量: {balanceLoading ? "加载中..." : (
                      userRawAmount === "0" ? "0" : Number(userRawAmount).toLocaleString()
                    )}
                  </span>
                  {!balanceLoading && Number(userRawAmount) > 0 && (
                    <button
                      type="button"
                      onClick={() => setAmount(userRawAmount)}
                      className="text-purple-400 hover:text-purple-300 transition-colors"
                    >
                      最大值
                    </button>
                  )}
                </div>
              )}

              <button
                onClick={handleTrade}
                disabled={loading}
                className={`pixel-btn w-full text-lg font-bold transition-colors ${
                  tradeMode === "buy"
                    ? "bg-green-600 hover:bg-green-700"
                    : "bg-red-600 hover:bg-red-700"
                } disabled:opacity-50 disabled:cursor-not-allowed`}
              >
                {loading ? "交易中..." : tradeMode === "buy" ? "Buy" : "Sell"}
              </button>
            </>
          )}
        </div>
      </div>
      </div>
    </>
  );
}
